interface TreeNode {
    [key: string]: any;
    children?: TreeNode[];
}

/**
 * 通用的推算树形结构节点路径的方法，支持根据指定的键（pathKey）或标签键（labelKey）生成路径。
 * @template T extends TreeNode 泛型类型，表示树节点的类型
 * @param list 树形结构的节点数组
 * @param pathKey 用于标识节点的键，默认为 'value'
 * @param labelKey 用于标识节点标签（如果为 null 则使用 pathKey），默认为 null
 * @param childrenKey 子节点的键，默认为 'children'
 * @returns 包含每个节点路径的对象，以 pathKey 为键，路径为值
 */
export function devPathEstimationGeneric<T extends TreeNode>(
    list: T[],
    pathKey: string = 'value',
    labelKey: string | null = null,
    childrenKey: string = 'children'
) {
    if (!Array.isArray(list) || list.length === 0) return {};

    const pathObject: Record<string, any> = {};

    const refreshPathList = (itemList: T[], superiorPath: any[] = []) => {
        itemList.forEach((item) => {
            const key = labelKey ? item[labelKey] : item[pathKey];
            const currentPath = [...superiorPath, key];
            pathObject[item[pathKey]] = currentPath;

            if (item[childrenKey] && item[childrenKey].length) {
                refreshPathList(item[childrenKey], currentPath);
            }
        });
    };

    refreshPathList(list);
    return pathObject;
}

/**
 * 推算树形结构中每个节点的完整对象路径，包含节点数据及其父级的完整路径数据。
 * @template T extends TreeNode 泛型类型，表示树节点的类型
 * @param list 树形结构的节点数组
 * @param pathKey 用于标识节点的键，默认为 'value'
 * @param childrenKey 子节点的键，默认为 'children'
 * @returns 包含每个节点的完整路径对象，以 pathKey 为键，完整对象为值
 */
export function devObjEstimation<T extends TreeNode>(
    list: T[],
    pathKey: string = 'value',
    labelKey: string = 'label',
    childrenKey: string = 'children'
) {
    if (!Array.isArray(list) || list.length === 0) return {};
    const pathObject: Record<string, any> = {};

    const refreshPathList = (itemList: T[], superiorPath: any = null) => {
        itemList.forEach((item,index:number) => {
            const currentData = {
                ...item,
                devAllData: superiorPath ? [...superiorPath.devAllData, item] : [item],
                devAllIndex: superiorPath ? [...superiorPath.devAllIndex, index] : [index],
                devAllLabel: superiorPath ? [...superiorPath.devAllLabel, item[labelKey]] : [item[labelKey]],
                devAllValue: superiorPath ? [...superiorPath.devAllValue, item[pathKey]] : [item[pathKey]],
            };
            pathObject[item[pathKey]] = currentData;
            if (item[childrenKey] && item[childrenKey].length) {
                refreshPathList(item[childrenKey], currentData);
            }
        });
    };

    refreshPathList(list);
    return pathObject;
}
